<template>
  <div class="xpage">
    <div class="left_obj">
      <div v-for="item in deviceTypeList" :key="item.label" draggable="true" @dragstart="handleDragStart($event, item)"
        class="draggable-item">
        <img style="width:50px;height:50px" :src="type_icon_map[item.type]" alt="">
        <div>
          {{ item.label }}
        </div>
      </div>

      <div class="draggable-item" @click="export_svg">
        toJSON() 导出
      </div>
    </div>

    <div ref="container" id="container" class="my_container" @dragover="handleDragOver" @drop="handleDrop"
      @contextmenu.prevent></div>

    <a-modal v-model:visible="modalVisible" :title="`编辑设备`" @ok="handleModalOk" @cancel="handleModalCancel">
      <!-- 设备名称选择 -->

      <div class="update_item">
        <span> 请输入设备名称: </span>

        <a-input style="width:160px" @change="change_device" v-model:value="deviceForm.deviceName" class="val_item">

        </a-input>
      </div>
      <div class="update_item">

        <span style="color:#fff">请选择需要绑定的设备: </span>
        <a-select style="width:160px" :field-names="{ label: 'label', value: 'deviceNo' }" class="val_item"
          v-model:value="deviceForm.deviceNo" :options="device_list" placeholder="请选择设备">
        </a-select>
      </div>
      <div class="update_item">
        <span style="color:#fff">请选择需要绑定的点位: </span>
        <a-select style="width:160px" :field-names="{ label: 'label', value: 'tagcode' }" @change="change_tagcode"
          class="val_item" mode="multiple" placeholder="请选择参数" :options="tagcode_ptions" />
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, computed, watch } from 'vue';
import { Graph } from '@antv/x6';
import { Modal as AModal, Form as AForm, FormItem as AFormItem, Input as AInput } from 'ant-design-vue';

import { Export } from '@antv/x6-plugin-export'

// 图标导入
import pcsIcon from '@/assets/svg_icon/icon01.svg';
import bmsIcon from '@/assets/svg_icon/icon02.svg';
import meterIcon from '@/assets/svg_icon/icon03.svg';

let container = ref(null);
let graph = ref(null);
let draggedItem = ref(null);
let modalVisible = ref(false);
let selectedDevice = ref(null);



let deviceForm = ref({
  deviceName: '',
  deviceNo: '',
  deviceTagcode: [
    {
      tagCode: "P",
      unit: 'kW',
      defaultValue: ''
    }
  ]
});

// 设备图标映射
let type_icon_map = {
  27: pcsIcon,
  28: bmsIcon,
  1: meterIcon,
};

// let type_icon_map = {
//   // ...
//   27: pcsIcon,
//   1: meterIcon
// };

// 设备参数配置
let deviceParamsConfig = {
  meter: [
    { key: 'power', label: '功率', unit: 'kW', defaultValue: '10' },
    { key: 'voltage', label: '电压', unit: 'V', defaultValue: '220' }
  ],
  pcs: [
    { key: 'capacity', label: '容量', unit: 'kWh', defaultValue: '50' },
    { key: 'efficiency', label: '效率', unit: '%', defaultValue: '95' }
  ],
  bms: [
    { key: 'cells', label: '电池数量', unit: '节', defaultValue: '16' },
    { key: 'temperature', label: '温度', unit: '°C', defaultValue: '25' }
  ]
};

let deviceTypeList = [
  { label: 'PCS', type: '27' },
  { label: 'BMS', type: '28' },
  { label: '电表1', type: '1' }
];

let connectingState = reactive({
  isConnecting: false,
  sourceNode: null,
  edge: null
});

let ports = {
  groups: {
    top: { position: 'top', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    right: { position: 'right', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    bottom: { position: 'bottom', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    left: { position: 'left', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
  },
  items: [
    { group: 'top' },
    { group: 'right' },
    { group: 'bottom' },
    { group: 'left' },
  ],
};

// 注册自定义节点
Graph.registerNode('device-node', {
  inherit: 'rect',
  markup: [
    { tagName: 'rect', selector: 'body' },
    { tagName: 'image', selector: 'image' },
    { tagName: 'text', selector: 'text' },
    { tagName: 'text', selector: 'params' }
  ],
  attrs: {
    body: {
      stroke: '#5F95FF',
      strokeWidth: 1,
      fill: '#EFF4FF',
      rx: 6,
      ry: 6
    },
    // image: {
    //   'xlink:href': '', // 初始留空，动态设置
    //   width: 40,
    //   height: 40,
    //   x: 10,
    //   y: 10
    // },

    image: {
      'xlink:href': '',
      width: 40,
      height: 40,
      refX: '50%',  // 横向参考点为节点中心
      refY: '50%',  // 纵向参考点为节点中心
      x: -20,       // 向左偏移图片宽度的一半（40/2）
      y: -40        // 向上偏移图片高度的一半（40/2）
    },
    text: {
      text: '设备',
      fontSize: 13,
      fill: '#262626',
      // refX: 0.5,
      // refY: '100%',
      // y: -10,

      // refX: '50%',  // 横向参考点为节点中心
      // refY: '50%',  // 纵向参考点为节点中心
      // x: -20,       // 向左偏移图片宽度的一半（40/2）
      // y: -20,

      refY: '65%',

      textAnchor: 'middle',

      alignmentBaseline: 'middle',

      // textAnchor: 'middle'
    },
    params: {
      // text: '',
      fontSize: 12,
      // fill: '#666',
      // refX: 0.5,
      // refY: '100%',
      // y: 5,
      // textAnchor: 'middle',
      refX: '50%',  // 横向参考点为节点中心

      refY: '80%',
      textAnchor: 'middle',
      alignmentBaseline: 'middle',

    }
  },
  ports: { ...ports },
}, true);

// 注册自定义连线
Graph.registerEdge('device-connection', {
  inherit: 'edge',
  attrs: {
    line: {
      stroke: '#1890ff',
      strokeWidth: 2,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8,
      },
    },
  },
  zIndex: 0,
}, true);

// 创建设备节点（优化版）
let createDeviceNode = (graph, item, position) => {
  let params = {};
  let paramsConfig = deviceParamsConfig[item.type] || [];
  paramsConfig.forEach(param => {
    params[param.key] = param.defaultValue;
  });

  let node = graph.createNode({
    shape: 'device-node',
    width: 120,
    height: 100,
    x: position.x,
    y: position.y,
    attrs: {
      image: {
        'xlink:href': type_icon_map[item.type], // 使用本地图标
        // width: 40,
        // height: 40,
        // x: 40,
        // y: 15
      },
      text: { text: item.label, },
      params: {
        text: paramsConfig.map(p => `${p.label}: ${params[p.key]}${p.unit}`).join('\n')
      }
    },
    data: {
      type: item.type,
      label: item.label,
      params: params,

      deviceNo: '', // 初始为空
      deviceModel: null,
      selectedParam: []
    }
  });

  // 添加悬停交互
  node.on('mouseenter', () => {
    node.attr('body/stroke', '#1890ff');
    node.attr('body/strokeWidth', 2);
  });
  node.on('mouseleave', () => {
    node.attr('body/stroke', '#5F95FF');
    node.attr('body/strokeWidth', 1);
  });

  return node;
};

// let updateNodeParamsDisplay = (node) => {
//   let paramsConfig = deviceParamsConfig[node.data.type] || [];
//   node.attr('params/text',
//     paramsConfig.map(p => `${p.label}: ${node.data.params[p.key]}${p.unit}`).join('\n'));
// };


function export_svg() {
  setTimeout(() => {

    //  let svg= document.getElementsByClassName('x6-graph-svg')[0];

    //  window.sessionStorage.setItem("svg_ele",svg.outerHTML)

    graph.value = JSON.parse(JSON.stringify(graph.value))

    graph.value.toJSON()
    // graph.value.use(new Export());
    // graph.value.exportSVG("exp")



  }, 3000)
}

// let updateNodeParamsDisplay = (node, data_res) => {



//   console.log("node_update", node);

//   let tagcode_text = '';

//   data_res.deviceTagcode.forEach((item, key) => {
//     tagcode_text += item.label + ":" + item.defaultValue + item.unit + "\n"
//   });



//   node.attr('params/text', `${tagcode_text}`);

//   node.attr('text/text', `${data_res.deviceName}`);
// };

let updateNodeParamsDisplay = (node, data_res) => {
  // 生成带占位符的参数文本
  let tagcode_text = data_res.deviceTagcode
    .map(item => {
      // 当 deviceNo 存在时生成 {{deviceNo.tagcode}} 格式
      const placeholder = data_res.deviceNo
        ? `{{de${data_res.deviceNo}.${item.tagcode}}}`
        : '{{未绑定设备}}'; // 未绑定时的默认显示

      return `${item.label}:${placeholder}${item.unit}`
    })
    .join('\n');

  // 更新节点显示
  node.attr('params/text', tagcode_text);
  node.attr('text/text', data_res.deviceName);
};


// 拖拽逻辑（优化版）
let handleDragStart = (e, item) => {
  draggedItem.value = item;

  // 创建拖拽预览
  let dragImage = new Image();
  dragImage.src = type_icon_map[item.type];
  dragImage.width = 50;
  dragImage.height = 50;

  // 创建克隆元素
  let cloneElement = e.target.cloneNode(true);
  cloneElement.style.position = 'absolute';
  cloneElement.style.pointerEvents = 'none';
  cloneElement.style.opacity = '0.7';
  document.body.appendChild(cloneElement);

  setTimeout(() => {
    e.dataTransfer.setDragImage(dragImage, 25, 25);
    e.dataTransfer.effectAllowed = 'copy';
  }, 0);

  // 清理克隆元素
  let dragEndHandler = () => {
    document.body.removeChild(cloneElement);
    e.target.removeEventListener('dragend', dragEndHandler);
  };
  e.target.addEventListener('dragend', dragEndHandler);
};

let handleDragOver = (e) => {
  e.preventDefault();
  e.dataTransfer.dropEffect = 'copy';
};

let handleDrop = (e) => {
  e.preventDefault();
  if (!draggedItem.value || !graph.value) return;

  let point = graph.value.clientToLocal(e.clientX, e.clientY);
  let node = createDeviceNode(graph.value, draggedItem.value, point);
  graph.value.addNode(node);
  draggedItem.value = null;
};

// 其他原有方法保持不变...
// [保持原有的 showEditModal、handleModalOk、handleModalCancel 等方法]
// [保持原有的连线逻辑 initConnection、startConnection 等方法]



onMounted(() => {
  graph.value = new Graph({
    panning: { enabled: true, modifiers: 'space', eventTypes: "leftMouseDown" },
    scaling: { min: 0.05, max: 1 },
    mousewheel: {
      enabled: true,
      modifiers: ['ctrl', 'meta'],
      guard: (e) => !e.altKey
    },
    grid: {
      size: 10,
      visible: true,
      args: { color: '#a0a0a0', thickness: 1 }
    },
    container: container.value,
    connecting: { anchor: 'orth' },
  });

  graph.value.on('node:click', ({ node }) => {



    selectedDevice.value = node;

    showEditModal(node);
  });



  initConnection();

  // 添加示例节点（带图标）
  let sampleNode1 = createDeviceNode(graph.value,
    { label: '示例电表', type: 'meter' },
    { x: 100, y: 100 }
  );
  let sampleNode2 = createDeviceNode(graph.value,
    { label: '示例PCS', type: 'pcs' },
    { x: 300, y: 100 }
  );
  graph.value.addNode([sampleNode1, sampleNode2]);
});

// 模态框取消
let handleModalCancel = () => {
  modalVisible.value = false;
};

// 显示编辑模态框
let showEditModal = (node) => {


  let device_type = node.data.type;

  console.log("device_type", device_type);

  console.log("device_type", device_type);

  console.log("node", node)

  node.data.data_res



  // deviceParams.value = deviceParamsConfig[node.data.type] || [];

  // Object.keys(deviceForm.value).forEach(key => delete deviceForm.value[key]);

  // deviceParams.value.forEach(param => {
  //   deviceForm.value[param.key] = node.data.params[param.key];
  // });

  modalVisible.value = true;
};

// 参数配置映射
let paramConfigMap = {
  27: [
    { label: "功率", tagcode: "P", unit: "kW", defaultValue: '' },
    { label: "无功功率", tagcode: "Q", unit: "kW", defaultValue: '' }
  ],
  1: [
    { label: "电压", tagcode: "U", unit: "V", defaultValue: '' },
    { label: "电流", tagcode: "I", unit: "A", defaultValue: '' }
  ]
};

function change_device(a, b) {
  console.log(a, b)
}

// 设备选项列表
let device_list = ref([
  { label: "PCS1", deviceNo: '20210002', deviceModel: 27, },
  { label: "PCS2", deviceNo: '20210003', deviceModel: 27 },
  { label: "电表", deviceNo: '20210004', deviceModel: 1 }
]);


let tagcode_ptions = ref([]);



// let deviceForm = ref({
//   deviceNo: '',
//   deviceTagcode: [
//     {
//      label:"功率"
//       tagcode: "P",
//       unit: 'kW',
//       defaultValue: ''
//     }
//   ]
// });
function change_tagcode(a, b) {
  console.log(a, b);

  deviceForm.value.deviceTagcode = b;
}

watch(() => deviceForm.value.deviceNo, (a) => {

  console.log("watch", a);

  if (a) {
    let device_modal = (device_list.value.filter((item, key) => item.deviceNo == a)[0]).deviceModel;
    tagcode_ptions.value = paramConfigMap[device_modal]
  }


})


let deviceParams = ref([]);


// 修改保存处理方法
let handleModalOk = () => {
  if (!selectedDevice.value) return;

  console.log("selectedDevice", selectedDevice.value);

  console.log("deviceForm", deviceForm.value);

  // let data_res = {
  //   "deviceName": "PCS1",
  //   "deviceNo": "20210002",
  //   "deviceTagcode": [
  //     {
  //       "label": "功率",
  //       "tagcode": "P",
  //       "unit": "kW",
  //       "defaultValue": ""
  //     },
  //     {
  //       "label": "无功功率",
  //       "tagcode": "Q",
  //       "unit": "kW",
  //       "defaultValue": ""
  //     }
  //   ]
  // };

  // 更新设备数据
  let selectedDeviceInfo = device_list.value.find(
    opt => opt.deviceNo === deviceForm.value.deviceNo
  );

  selectedDevice.value.data = {
    ...selectedDevice.value.data,
    deviceNo: deviceForm.value.deviceNo,

    data_res: {
      ...deviceForm.value,
      // 确保参数列表包含 tagcode
      deviceTagcode: deviceForm.value.deviceTagcode.map(t => ({
        ...t,
        tagcode: t.tagcode // 确保属性名正确
      }))
    }

    // deviceModel: selectedDeviceInfo?.deviceModel,
    // selectedParam: deviceForm.value.selectedParam,
    // data_res: deviceForm.value
  };



  updateNodeParamsDisplay(selectedDevice.value, deviceForm.value);

  // graph.value.render();  // 添加画布重绘
  // graph.value.view.update();

  modalVisible.value = false;
};


let initConnection = () => {
  let arrowCursor = document.createElement('div');
  arrowCursor.style.position = 'absolute';
  arrowCursor.style.width = '20px';
  arrowCursor.style.height = '20px';
  arrowCursor.style.backgroundImage = 'url("")';
  arrowCursor.style.backgroundSize = 'contain';
  arrowCursor.style.pointerEvents = 'none';
  arrowCursor.style.zIndex = '1000';
  arrowCursor.style.display = 'none';
  document.body.appendChild(arrowCursor);

  let handleMouseMove = (e) => {
    if (connectingState.isConnecting) {
      arrowCursor.style.display = 'block';
      arrowCursor.style.left = `${e.clientX + 10}px`;
      arrowCursor.style.top = `${e.clientY + 10}px`;

      if (connectingState.edge) {
        let point = graph.value.clientToLocal(e.clientX, e.clientY);
        connectingState.edge.setTarget(point);
      }
    }
  };

  let handleMouseDown = (e) => {
    if (e.button === 2 && !connectingState.isConnecting) {
      let node = getNodeAtPoint(e.clientX, e.clientY);
      if (node) {
        startConnection(node, e.clientX, e.clientY);
      }
    }
  };

  let handleMouseUp = (e) => {
    if (e.button === 2 && connectingState.isConnecting) {
      let node = getNodeAtPoint(e.clientX, e.clientY);
      if (node && node.id !== connectingState.sourceNode.id) {
        completeConnection(node);
      } else {
        cancelConnection();
      }
    }
  };

  window.addEventListener('mousemove', handleMouseMove);
  window.addEventListener('mousedown', handleMouseDown);
  window.addEventListener('mouseup', handleMouseUp);

  onBeforeUnmount(() => {
    window.removeEventListener('mousemove', handleMouseMove);
    window.removeEventListener('mousedown', handleMouseDown);
    window.removeEventListener('mouseup', handleMouseUp);
    document.body.removeChild(arrowCursor);
  });
};

// 开始创建连线
let startConnection = (sourceNode, clientX, clientY) => {
  connectingState.isConnecting = true;
  connectingState.sourceNode = sourceNode;

  let point = graph.value.clientToLocal(clientX, clientY);
  connectingState.edge = graph.value.addEdge({
    shape: 'device-connection', // 直接使用注册的形状
    source: { cell: sourceNode.id },
    target: point,
    attrs: {
      line: {
        stroke: '#1890ff',
        strokeWidth: 2,
        targetMarker: {
          name: 'block',
          width: 12,
          height: 8,
        },
        strokeDasharray: '5 5',
      }
    },
    zIndex: 0,
  });
};

// 完成连线
let completeConnection = (targetNode) => {
  if (connectingState.edge) {
    // 移除临时连线
    graph.value.removeCell(connectingState.edge);

    // 创建正式连线
    let edge = graph.value.addEdge({
      shape: 'device-connection',
      source: { cell: connectingState.sourceNode.id },
      target: { cell: targetNode.id },
      attrs: {
        line: {
          stroke: '#1890ff',
          strokeWidth: 2,
          targetMarker: {
            name: 'block',
            width: 12,
            height: 8,
          },
        }
      },
      data: {
        type: 'connection',
        from: connectingState.sourceNode.data.label,
        to: targetNode.data.label,
        createdAt: new Date().toISOString()
      },
      zIndex: 0,
    });
  }

  resetConnectionState();
};

// 获取鼠标位置的节点（兼容X6 2.18.1版本）
let getNodeAtPoint = (clientX, clientY) => {
  if (!graph.value) return null;

  let point = graph.value.clientToLocal(clientX, clientY);
  let nodes = graph.value.getNodes();

  // 使用getBBox判断节点是否包含点
  for (let i = nodes.length - 1; i >= 0; i--) {
    let node = nodes[i];
    let bbox = node.getBBox();
    if (bbox.containsPoint(point)) {
      return node;
    }
  }

  return null;
};

// 取消连线
let cancelConnection = () => {
  if (connectingState.edge) {
    graph.value.removeCell(connectingState.edge);
  }
  resetConnectionState();
};

// 重置连线状态
let resetConnectionState = () => {
  connectingState.isConnecting = false;
  connectingState.sourceNode = null;
  connectingState.edge = null;
  document.querySelectorAll('.arrow-cursor').forEach(el => el.style.display = 'none');
};

</script>

<style scoped>
/* 原有样式保持不变... */
.xpage {
  height: 100vh;
  display: flex;
}

.my_container {
  flex: 1;
  height: 100%;
  border: 1px solid #d9d9d9;
  background: #f5f5f5;
}

.left_obj {
  background-color: #fff;
  width: 120px;
  padding: 10px;
  border-right: 1px solid #d9d9d9;
}

.draggable-item {
  background-color: #e0d6d6;
  color: #333;
  text-align: center;
  border-radius: 10px;
  cursor: move;
  margin-bottom: 10px;
  user-select: none;
  transition: all 0.3s;
  border: 1px solid gray;
  padding: 10px;
  width: 100%;
}

.draggable-item:hover {
  background-color: #40a9ff;
  transform: translateX(5px);
}
</style>

<style>
/* 新增全局样式 */
.x6-node [attrs*="image"] {
  transition: transform 0.2s ease-in-out;
}

.x6-node:hover [attrs*="image"] {
  transform: scale(1.1);
}

.x6-node:hover [attrs*="body"] {
  filter: drop-shadow(0 2px 8px rgba(24, 144, 255, 0.15));
}

.x6-edge path {
  animation: edge-flow 1s linear infinite;
}

@keyframes edge-flow {
  from {
    stroke-dashoffset: 0;
  }

  to {
    stroke-dashoffset: -20;
  }
}

:deep(.ant-form-vertical .ant-form-item-label>label) {
  color: #fff !important;
  ;
}

.update_item {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-top: 20px;
}

.update_item>span {

  text-align: right;
  color: #fff;
  margin-right: 10px;
  max-width: 160px;
  flex: 0.5;
}

.update_item .val_item {
  max-width: 250px;
  flex: 1;

}
</style>